Skip to content

aes-kw: add optional zeroize feature for wrappers#80

Merged
newpavlov merged 5 commits into
RustCrypto:masterfrom
Xynnn007:aes-kw/zeroize
May 27, 2026
Merged

aes-kw: add optional zeroize feature for wrappers#80
newpavlov merged 5 commits into
RustCrypto:masterfrom
Xynnn007:aes-kw/zeroize

Conversation

@Xynnn007
Copy link
Copy Markdown
Contributor

Close #79

@baloo
Copy link
Copy Markdown
Member

baloo commented May 20, 2026

ZeroizeOnDrop is only a marker trait. Here you marked the objects as "pinky promise, this will be zerorized" but not actually zeroized.

I think you wanted to #[derive(Zeroize)] instead, or more precisely: #[cfg_attr(feature = "zeroize", derive(zeroize::ZeroizeOnDrop))] which would implement zeroize and mark the objects.

@newpavlov
Copy link
Copy Markdown
Member

I believe that the implementation is correct. The types just wrap C and the impl says "pinky promise, this will be zeroized, assuming that the cipher's pinky's promise is true".

@baloo
Copy link
Copy Markdown
Member

baloo commented May 20, 2026

That's true, but I'd rather have the explicit impl Drop { self.field.zeroize() } to be refactor resistant though (in case there is an additional field in the downstream struct) as it should be essentially free.

@newpavlov
Copy link
Copy Markdown
Member

newpavlov commented May 20, 2026

It's not possible. The block cipher implementations intentionally do not implement Zeroize (but do ZeroizeOnDrop and Drop with zeroizing impl) since "zeroized" state may not be a valid block cipher state and explicitly zeroizing block cipher is likely to be a mistake either way.

Meanwhile, #[derive(ZeroizeOnDrop)] will result in the exactly same impl, but at the cost of pulling the proc macro dependency.

@Xynnn007
Copy link
Copy Markdown
Contributor Author

A common case, we use KwAes256 which is AesKw<aes::Aes256> where C is Aes256, defined almost like

        #[derive(Clone)]
        pub struct Aes256 {
            encrypt: Aes256Enc,
            decrypt: Aes256Dec,
        }
...
#[cfg(feature = "zeroize")]
impl zeroize::ZeroizeOnDrop for Aes256 {}
...

#[derive(Clone)]
        pub struct Aes256Enc {
            backend: Aes256BackEnc,
        }

impl Drop for Aes256Enc {
            #[inline]
            fn drop(&mut self) {
                #[cfg(feature = "zeroize")]
                unsafe {
                    zeroize::zeroize_flat_type(&mut self.backend)
                }
            }
        }

That means Aes256's Drop will call each components' drop - finally zeroize underlying data.

Thus we do not need to impl explicitly the Drop on top level. But need to impl the ZeroizeOnDrop trait when zeroize feature is on, or we cannot use Zeroizing::new(KwAes256) as the compiler will cry.

Not sure if I made anything wrong

@newpavlov
Copy link
Copy Markdown
Member

Please rebase or merge master to fix the CI failure.

Close RustCrypto#79

Signed-off-by: Xynnn007 <xynnn@linux.alibaba.com>
@Xynnn007
Copy link
Copy Markdown
Contributor Author

@newpavlov Thanks! Rebased

@newpavlov newpavlov merged commit 54f856a into RustCrypto:master May 27, 2026
16 checks passed
@newpavlov newpavlov mentioned this pull request May 27, 2026
newpavlov added a commit that referenced this pull request May 27, 2026
### Added
- Implementation of `Copy`, `Clone`, and `Hash` traits for `Error`
([#78])
- Implementation of `ZeroizeOnDrop` gated on `zeroize` crate feature
([#80])

### Changed
- Use `doc_cfg` instead of `doc_auto_cfg` ([#83])

[#78]: #78
[#80]: #80
[#83]: #83
@Xynnn007 Xynnn007 deleted the aes-kw/zeroize branch May 27, 2026 17:34
@Xynnn007
Copy link
Copy Markdown
Contributor Author

@newpavlov Thanks for getting this in! Could you help to take a look at RustCrypto/AEADs#827 also?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

aes-kw: add zeroize feature to clear key material in AesKw / KwAes256 on drop

3 participants